home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
frasrc19.zip
/
FRACTINT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-04
|
18KB
|
571 lines
/*
FRACTINT - The Ultimate Fractal Generator
Main Routine
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#ifndef XFRACT
#include <io.h>
#include <dos.h>
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <ctype.h>
#include "prototyp.h"
#include "fractype.h"
#include "helpdefs.h"
struct videoinfo videoentry;
int helpmode;
long timer_start,timer_interval; /* timer(...) start & total */
int adapter; /* Video Adapter chosen from list in ...h */
char *fract_dir1="", *fract_dir2="";
#ifdef __TURBOC__
/* yes, I *know* it's supposed to be compatible with Microsoft C,
but some of the routines need to know if the "C" code
has been compiled with Turbo-C. This flag is a 1 if FRACTINT.C
(and presumably the other routines as well) has been compiled
with Turbo-C. */
int compiled_by_turboc = 1;
/* set size to be used for overlays, a bit bigger than largest (help) */
unsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */
#else
int compiled_by_turboc = 0;
#endif
/*
the following variables are out here only so
that the calcfract() and assembler routines can get at them easily
*/
int active_system = 0; /* 0 for DOS, WINFRAC for Windows */
int dotmode; /* video access method */
int textsafe2; /* textsafe override from videotable */
int oktoprint; /* 0 if printf() won't work */
int sxdots,sydots; /* # of dots on the physical screen */
int sxoffs,syoffs; /* physical top left of logical screen */
int xdots, ydots; /* # of dots on the logical screen */
double dxsize, dysize; /* xdots-1, ydots-1 */
int colors; /* maximum colors available */
long maxit; /* try this many iterations */
int boxcount; /* 0 if no zoom-box yet */
int zrotate; /* zoombox rotation */
double zbx,zby; /* topleft of zoombox */
double zwidth,zdepth,zskew; /* zoombox size & shape */
int fractype; /* if == 0, use Mandelbrot */
char stdcalcmode; /* '1', '2', 'g', 'b' */
long creal, cimag; /* real, imag'ry parts of C */
long delx, dely; /* screen pixel increments */
long delx2, dely2; /* screen pixel increments */
LDBL delxx, delyy; /* screen pixel increments */
LDBL delxx2, delyy2; /* screen pixel increments */
long delmin; /* for calcfrac/calcmand */
double ddelmin; /* same as a double */
double param[MAXPARAMS]; /* parameters */
double potparam[3]; /* three potential parameters*/
long fudge; /* 2**fudgefactor */
long l_at_rad; /* finite attractor radius */
double f_at_rad; /* finite attractor radius */
int bitshift; /* fudgefactor */
int badconfig = 0; /* 'fractint.cfg' ok? */
int diskisactive; /* disk-video drivers flag */
int diskvideo; /* disk-video access flag */
int hasinverse = 0;
/* note that integer grid is set when integerfractal && !invert; */
/* otherwise the floating point grid is set; never both at once */
long far *lx0, far *ly0; /* x, y grid */
long far *lx1, far *ly1; /* adjustment for rotate */
/* note that lx1 & ly1 values can overflow into sign bit; since */
/* they're used only to add to lx0/ly0, 2s comp straightens it out */
double far *dx0, far *dy0; /* floating pt equivs */
double far *dx1, far *dy1;
int integerfractal; /* TRUE if fractal uses integer math */
/* usr_xxx is what the user wants, vs what we may be forced to do */
char usr_stdcalcmode;
int usr_periodicitycheck;
int usr_distest;
char usr_floatflag;
int viewwindow; /* 0 for full screen, 1 for window */
float viewreduction; /* window auto-sizing */
int viewcrop; /* nonzero to crop default coords */
float finalaspectratio; /* for view shape and rotation */
int viewxdots,viewydots; /* explicit view sizing */
HISTORY far *history = NULL;
int maxhistory = 10;
/* variables defined by the command line/files processor */
int comparegif=0; /* compare two gif files flag */
int timedsave=0; /* when doing a timed save */
int resave_flag=0; /* tells encoder not to incr filename */
int started_resaves=0; /* but incr on first resave */
int save_system; /* from and for save files */
int tabmode = 1; /* tab display enabled */
/* for historical reasons (before rotation): */
/* top left corner of screen is (xxmin,yymax) */
/* bottom left corner of screen is (xx3rd,yy3rd) */
/* bottom right corner of screen is (xxmax,yymin) */
double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
long xmin, xmax, ymin, ymax, x3rd, y3rd; /* integer equivs */
double sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen multipliers */
int calc_status; /* -1 no fractal */
/* 0 parms changed, recalc reqd */
/* 1 actively calculating */
/* 2 interrupted, resumable */
/* 3 interrupted, not resumable */
/* 4 completed */
long calctime;
int max_colors; /* maximum palette size */
int zoomoff; /* = 0 when zoom is disabled */
int savedac; /* save-the-Video DAC flag */
int browsing; /* browse mode flag */
char file_name_stack[16][13]; /* array of file names used while browsing */
int name_stack_ptr ;
double toosmall;
int minbox;
int no_sub_images;
int autobrowse,doublecaution;
char brwscheckparms,brwschecktype;
char browsemask[13];
#define RESTART 1
#define IMAGESTART 2
#define RESTORESTART 3
#define CONTINUE 4
static void check_samename(void)
{
char drive[FILE_MAX_DRIVE];
char dir[FILE_MAX_DIR];
char fname[FILE_MAX_FNAME];
char ext[FILE_MAX_EXT];
char path[FILE_MAX_PATH];
splitpath(savename,drive,dir,fname,ext);
if(strcmp(fname,"fract001"))
{
makepath(path,drive,dir,fname,"gif");
if(access(path,0)==0)
exit(0);
}
}
/* Do nothing if math error */
static void my_floating_point_err(int sig)
{
if(sig != 0)
overflow = 1;
}
void main(int argc, char **argv)
{
int resumeflag;
int kbdchar; /* keyboard key-hit value */
int kbdmore; /* continuation variable */
char stacked=0; /* flag to indicate screen stacked */
/* this traps non-math library floating point errors */
signal( SIGFPE, my_floating_point_err );
initasmvars(); /* initialize ASM stuff */
checkfreemem(0);
load_videotable(1); /* load fractint.cfg, no message yet if bad */
#ifdef XFRACT
UnixInit();
#endif
init_help();
restart: /* insert key re-starts here */
autobrowse = FALSE;
brwschecktype = TRUE;
brwscheckparms = TRUE;
doublecaution = TRUE;
no_sub_images = FALSE;
toosmall = 6;
minbox = 3;
strcpy(browsemask,"*.GIF");
strcpy(browsename," ");
name_stack_ptr= -1; /* init loaded files stack */
if (fract_dir1==NULL)
fract_dir1 = ".";
cmdfiles(argc,argv); /* process the command-line */
dopause(0); /* pause for error msg if not batch */
init_msg(0,"",NULL,0); /* this causes getakey if init_msg called on runup */
checkfreemem(1);
if(debugflag==450 && initbatch==1) /* abort if savename already exits */
check_samename();
#ifdef XFRACT
initUnixWindow();
#endif
memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */
if (debugflag == 8088) cpu = 86; /* for testing purposes */
if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
if (debugflag == 870 && fpu >= 87 ) fpu = 87; /* for testing purposes */
if (debugflag == 70) fpu = 0; /* for testing purposes */
if (getenv("NO87")) fpu = 0;
fract_dir1 = getenv("FRACTDIR");
if (fract_dir1==NULL) {
fract_dir1 = ".";
}
#ifdef SRCDIR
fract_dir2 = SRCDIR;
#else
fract_dir2 = ".";
#endif
if (fpu == 0) iit = 0;
if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
setup287code();
/* IIT math coprocessor chip logic */
if(iit == 0 && fpu)
if(IITCoPro())
iit = 3; /* detect iit chip */
if(iit < 0) iit = 0; /* user wants chip turned off */
if(iit>0)
{
if(F4x4Check())
iit = 2; /* semaphore TSR is installed */
else if(iit == 3)
iit = 0; /* we detetct chip but no tsr - don't use */
/* else user forced iit == 1 */
}
adapter_detect(); /* check what video is really present */
if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
if (video_type > (debugflag-9000)/2) /* adjust the video value */
video_type = (debugflag-9000)/2;
diskisactive = 0; /* disk-video is inactive */
diskvideo = 0; /* disk driver is not in use */
setvideotext(); /* switch to text mode */
calc_status = -1; /* no active fractal image */
savedac = 0; /* don't save the VGA DAC */
#ifndef XFRACT
if (debugflag == 10000) /* check for free memory */
showfreemem();
if (badconfig < 0) /* fractint.cfg bad, no msg yet */
bad_fractint_cfg_msg();
#endif
max_colors = 256; /* the Windows version is lower */
max_kbdcount=(cpu==386) ? 80 : 30; /* check the keyboard this often */
if (showfile && initmode < 0) {
intro(); /* display the credits screen */
if (keypressed() == ESC) {
getakey();
goodbye();
}
}
browsing = FALSE;
if (!functionpreloaded)
set_if_old_bif();
stacked = 0;
restorestart:
if (colorpreloaded)
memcpy(dacbox,olddacbox,256*3); /* restore in case colors= present */
lookatmouse = 0; /* ignore mouse */
while (showfile <= 0) { /* image is to be loaded */
char *hdg;
tabmode = 0;
if (!browsing ) /*RB*/
{
if (overlay3d) {
hdg = "Select File for 3D Overlay";
helpmode = HELP3DOVLY;
}
else if (display3d) {
hdg = "Select File for 3D Transform";
helpmode = HELP3D;
}
else {
hdg = "Select File to Restore";
helpmode = HELPSAVEREST;
}
if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
showfile = 1; /* cancelled */
initmode = -1;
break;
}
name_stack_ptr = 0; /* 'r' reads first filename for browsing */
strcpy(file_name_stack[name_stack_ptr],browsename);
}
showfile = 0;
helpmode = -1;
tabmode = 1;
if(stacked)
{
discardscreen();
setvideotext();
stacked = 0;
}
if (read_overlay() == 0) /* read hdr, get video mode */
break; /* got it, exit */
showfile = -1; /* retry */
}
helpmode = HELPMENU; /* now use this help mode */
tabmode = 1;
lookatmouse = 0; /* ignore mouse */
if ((overlay3d || stacked) && initmode < 0) { /* overlay command failed */
unstackscreen(); /* restore the graphics screen */
stacked = 0;
overlay3d = 0; /* forget overlays */
display3d = 0; /* forget 3D */
if (calc_status > 0 && calc_status !=2)
calc_status = 0;
resumeflag = 1;
goto resumeloop; /* ooh, this is ugly */
}
savedac = 0; /* don't save the VGA DAC */
imagestart: /* calc/display a new image */
if(stacked)
{
discardscreen();
stacked = 0;
}
#ifdef XFRACT
usr_floatflag = 1;
#endif
got_status = -1; /* for tab_display */
if (showfile)
if (calc_status > 0) /* goto imagestart implies re-calc */
calc_status = 0;
if (initbatch == 0)
lookatmouse = -PAGE_UP; /* just mouse left button, == pgup */
cyclelimit = initcyclelimit; /* default cycle limit */
adapter = initmode; /* set the video adapter up */
initmode = -1; /* (once) */
while (adapter < 0) { /* cycle through instructions */
if (initbatch) { /* batch, nothing to do */
initbatch = 4; /* exit with error condition set */
goodbye();
}
kbdchar = main_menu(0);
if (kbdchar == INSERT) goto restart; /* restart pgm on Insert Key */
if (kbdchar == DELETE) /* select video mode list */
kbdchar = select_video_mode(-1);
if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
break; /* got a video mode now */
#ifndef XFRACT
if ('A' <= kbdchar && kbdchar <= 'Z')
kbdchar = tolower(kbdchar);
#endif
if (kbdchar == 'd') { /* shell to DOS */
setclear();
printf("\n\nShelling to DOS - type 'exit' to return\n\n");
shell_to_dos();
goto imagestart;
}
#ifndef XFRACT
if (kbdchar == '@' || kbdchar == '2') { /* execute commands */
#else
if (kbdchar == F2 || kbdchar == '@') { /* We mapped @ to F2 */
#endif
if ((get_commands() & 4) == 0)
goto imagestart;
kbdchar = '3'; /* 3d=y so fall thru '3' code */
}
#ifndef XFRACT
if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') {
#else
if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) {
#endif
display3d = 0;
if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3)
display3d = 1;
if(colorpreloaded)
memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */
setvideotext(); /* switch to text mode */
showfile = -1;
goto restorestart;
}
if (kbdchar == 't') { /* set fractal type */
julibrot = 0;
get_fracttype();
goto imagestart;
}
if (kbdchar == 'x') { /* generic toggle switch */
get_toggles();
goto imagestart;
}
if (kbdchar == 'y') { /* generic toggle switch */
get_toggles2();
goto imagestart;
}
if (kbdchar == 'z') { /* type specific parms */
get_fract_params(1);
goto imagestart;
}
if (kbdchar == 'v') { /* view parameters */
get_view_params();
goto imagestart;
}
if (kbdchar == 2) { /* ctrl B = browse parms*/
get_browse_params();
goto imagestart;
}
if (kbdchar == 'f') { /* floating pt toggle */
if (usr_floatflag == 0)
usr_floatflag = 1;
else
usr_floatflag = 0;
goto imagestart;
}
if (kbdchar == 'i') { /* set 3d fractal parms */
get_fract3d_params(); /* get the parameters */
goto imagestart;
}
if (kbdchar == 'g') {
get_cmd_string(); /* get command string */
goto imagestart;
}
/* buzzer(2); */ /* unrecognized key */
}
zoomoff = 1; /* zooming is enabled */
helpmode = HELPMAIN; /* now use this help mode */
resumeflag = 0; /* allows taking goto inside big_while_loop() */
resumeloop:
/* this switch processes gotos that are now inside function */
switch(big_while_loop(&kbdmore,&stacked,resumeflag))
{
case RESTART:
goto restart;
case IMAGESTART:
goto imagestart;
case RESTORESTART:
goto restorestart;
default:
break;
}
}
int check_key()
{
int key;
if((key = keypressed()) != 0) {
if(key != 'o' && key != 'O') {
fflush(stdout);
return(-1);
}
getakey();
if (dotmode != 11)
show_orbit = 1 - show_orbit;
}
return(0);
}
/* timer function:
timer(0,(*fractal)()) fractal engine
timer(1,NULL,int width) decoder
timer(2) encoder
*/
#ifndef XFRACT
int timer(int timertype,int(*subrtn)(),...)
#else
int timer(va_alist)
va_dcl
#endif
{
va_list arg_marker; /* variable arg list */
char *timestring;
time_t ltime;
FILE *fp = NULL;
int out=0;
int i;
int do_bench;
#ifndef XFRACT
va_start(arg_marker,subrtn);
#else
int timertype;
int (*subrtn)();
va_start(arg_marker);
timertype = va_arg(arg_marker, int);
subrtn = (int (*)())va_arg(arg_marker, int *);
#endif
do_bench = timerflag; /* record time? */
if (timertype == 2) /* encoder, record time only if debug=200 */
do_bench = (debugflag == 200);
if(do_bench)
fp=dir_fopen(workdir,"bench","a");
timer_start = clock_ticks();
switch(timertype) {
case 0:
out = (*(int(*)(void))subrtn)();
break;
case 1:
i = va_arg(arg_marker,int);
out = (int)decoder((short)i); /* not indirect, safer with overlays */
break;
case 2:
out = encoder(); /* not indirect, safer with overlays */
break;
}
/* next assumes CLK_TCK is 10^n, n>=2 */
timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100);
if(do_bench) {
time(<ime);
timestring = ctime(<ime);
timestring[24] = 0; /*clobber newline in time string */
switch(timertype) {
case 1:
fprintf(fp,"decode ");
break;
case 2:
fprintf(fp,"encode ");
break;
}
fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%ld",
timestring,
curfractalspecific->name,
xdots,
ydots,
maxit);
fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
if(fp != NULL)
fclose(fp);
}
return(out);
}